const config = {
  entry: './core/main.js',
  output: './build/test-output.js',
  context: './core'
}
const fs = require('fs')
const path = require('path')
const ejs = require('ejs')
const r = path.resolve

let entryFile = fs.readFileSync(config.entry, 'utf-8') // 读取入口文件
const sourcePath = r(__dirname, config.context) // 获取上下文
const filesList = [] // 文件栈(深度 => 长度) 依赖文件

function complier (ctn, context) {
  const reqRex = /(require)\(['"](.+?)["']\)/g // 正则匹配require，后面替换
  ctn = ctn.replace(reqRex, (s, $1, $2) => {
    let p = r(context, $2.trim())
    let fileText = fs.readFileSync(p, 'utf-8') // 读取依赖文件
    if (reqRex.test(fileText)) {
      // 如果存在依赖继续递归同时建立新的上下文
      const newCtx = p.slice(0, p.lastIndexOf('/'))
      fileText = complier(fileText, newCtx)
    }
    filesList.push(fileText)
    return `__req__(${filesList.length})`
  })
  return ctn
}
const template = `
  ;(function (modules) {
    const installModules = {}
    function __req__(moduleId) {
      if (installModules[moduleId]) return installModules[moduleId]
      const module = (installModules[moduleId] = {
        l: false,
        i: moduleId,
        exports: {}
      })
      modules[moduleId].call(module.exports, module, module.exports, __req__)
      module.l = true
      return module.exports
    }
  return __req__(0)
  })([
    (function (module, exports, __req__) {
      <%- entryFile %>
    }),<% for(var i = 0, len = filesList.length; i < len; i++) { %>
    (function (module, exports, __req__) {
      <%- filesList[i] %>
    }),<% } %>
  ])
`
entryFile = complier(entryFile, sourcePath)
let result = ejs.render(template, {
  entryFile,
  filesList
})
fs.writeFile(
  r(__dirname, config.output),
  result,
  err => err && console.log(err)
)